<?php
/**
 * bos 清理事件监听
 *
 * Author: Zeon
 * Date: 2018/1/17
 * Created by Panxsoft.
 */
namespace App\Observers;

use App\Services\Utils\Bosable;
use Illuminate\Database\Eloquent\Model;

class BosCleanObserver
{
    use Bosable;

    const COLUMNS_PROPERTY = 'bos_columns';

    /**
     * @param Model $model
     */
    public function updated(Model $model)
    {
        $this->mapDeleteBosKeys($this->getChangedOriginalBosKeys($model));
    }

    /**
     * @param Model $model
     */
    public function deleted(Model $model)
    {
        $this->mapDeleteBosKeys($this->getOriginalBosKeys($model, $this->getBosColumns($model)));
    }

    /**
     * @param Model $model
     * @param array $bos_columns
     * @return array
     */
    private function getOriginalBosKeys(Model $model, array $bos_columns)
    {
        return array_map([$model, 'getOriginal'], $bos_columns);
    }

    /**
     * @param array $keys
     * @return array
     */
    private function mapDeleteBosKeys(array $keys)
    {
        return array_map([$this, 'deleteBosKey'], $keys);
    }

    /**
     * 返回更新后已经改变的 bos keys 的原始（需要被清理删除的）值
     *
     * @param Model $model
     * @return array
     */
    private function getChangedOriginalBosKeys(Model $model)
    {
        $dirty_columns = array_keys($model->getDirty());

        $bos_columns = $this->getBosColumns($model);

        $dirty_bos_columns = array_values(array_intersect($bos_columns, $dirty_columns));

        $original_bos_keys = $this->getOriginalBosKeys($model, $dirty_bos_columns);

        return $original_bos_keys;
    }

    /**
     * @param Model $model
     * @return array|mixed
     */
    private function getBosColumns(Model $model)
    {
        if (! property_exists($model, self::COLUMNS_PROPERTY)) return [];

        if (! is_array($model->{self::COLUMNS_PROPERTY})) return [];

        return $model->{self::COLUMNS_PROPERTY};
    }
}
